home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Just Call Me Internet
/
Just Call Me Internet.iso
/
prog
/
atari
/
c
/
nos042_s
/
arp.p
< prev
next >
Wrap
Text File
|
1993-12-28
|
62KB
|
1,961 lines
/* Address Resolution Protocol (ARP) functions. Sits between IP and
* Level 2, mapping IP to Level 2 addresses for all outgoing datagrams.
* Copyright 1991 Phil Karn, KA9Q
*/
/****************************************************************************
* $Id: arp.c 1.2 93/07/16 11:41:45 ROOT_DOS Exp $
* 14 Jun 93 1.2 GT Fix warnings. *
*
* ATARI Version by David Nash - dnash@chaos.demon.co.uk
*
* ANSI style function definitions
*
****************************************************************************/
/****************************************************************************
* $Id: global.h 1.6 93/07/16 11:44:56 ROOT_DOS Exp $
* 24 Aug 92 1.3 GT Redefine time. *
* 13 Sep 92 1.4 GT New file modes. *
* 09 May 93 1.6 GT Fix warnings. *
*
* ATARI Version by David Nash - dnash@chaos.demon.co.uk
*
* stdio.h and stdlib included
* shadow definitions added for fileops
*
****************************************************************************/
/* Global definitions used by every source file.
* Some may be compiler dependent.
*/
/**
* $Id: stdio.h,v 1.1 1993/11/14 14:43:52 AGK Rel $
*
* ANSI I/O interface file
*
* (c) Copyright 1989, 1992, 1993 HiSoft
**/
/**
* $Id: __types.h,v 1.1 1993/11/14 14:42:42 AGK Rel $
*
* Library type definitions
*
* (c) Copyright 1992, 1993 HiSoft
**/
/* ANSI X3.159-1989 types */
typedef long __clock_t;
typedef long int __ptrdiff_t;
typedef unsigned long __size_t;
typedef long __time_t;
typedef unsigned char __wchar_t;
typedef char *__va_list;
/* ISO/IEC 9945-1:1990 types */
typedef long __off_t;
typedef short __nlink_t;
typedef short __pid_t;
typedef signed long __ssize_t;
typedef unsigned short __dev_t;
typedef unsigned short __gid_t;
typedef unsigned short __mode_t;
typedef unsigned short __uid_t;
typedef unsigned long __ino_t;
typedef unsigned long __sigset_t;
typedef __size_t size_t;
long __regargs _CXCERR(long); /* always __regargs for efficiency */
typedef unsigned long fpos_t;
/**
*
* Definitions associated with _iobuf._flag
*
**/
typedef struct _iobuf {
struct _iobuf *_next;
unsigned char *_ptr; /* current buffer pointer */
int _rcnt; /* current byte count for reading */
int _wcnt; /* current byte count for writing */
unsigned char *_base; /* base address of I/O buffer */
int _size; /* size of buffer */
int _flag; /* control flags */
int _file; /* file descriptor */
unsigned char _cbuff; /* single char buffer */
} FILE;
extern struct _iobuf _iob[];
/*
* Prototypes for ANSI standard functions.
*/
int rename(const char *,const char *);
long _lgscc(int,int,const char *,const char *);
int remove(const char *);
long _lgc(int,const char *);
FILE *tmpfile(void);
char *tmpnam(char *s);
int fclose(FILE *);
int fflush(FILE *);
FILE *fopen(const char *, const char *);
FILE *freopen(const char *, const char *, FILE *);
void setbuf(FILE *, char *);
int setvbuf(FILE *, char *, int, size_t);
int fprintf(FILE *, const char *, ...);
int fscanf(FILE *, const char *, ...);
int printf(const char *, ...);
int lprintf(const char *, ...);
int scanf(const char *, ...);
int sprintf(char *, const char *, ...);
int sscanf(const char *, const char *, ...);
int vfprintf(FILE *, const char *, char *);
int vprintf(const char *, char *);
int vsprintf(char *, const char *, char *);
int __builtin_printf(const char *, ...);
int fgetc(FILE *);
char *fgets(char *, int, FILE *);
int fputc(int, FILE *);
int fputs(const char *, FILE *);
int getc(FILE *);
int getchar(void);
char *gets(char *);
int putc(int, FILE *);
int putchar(int);
int puts(const char *);
int ungetc(int, FILE *);
size_t fread(void *, size_t, size_t, FILE *);
size_t fwrite(const void *, size_t, size_t, FILE *);
int fgetpos(FILE *, fpos_t *);
int fseek(FILE *, long int, int);
int fsetpos(FILE *, const fpos_t *);
long int ftell(FILE *);
void rewind(FILE *);
void clearerr(FILE *);
int feof(FILE *);
int ferror(FILE *);
void perror(const char *);
/*
* Prototypes for Non-ANSI functions.
*/
int fcloseall(void);
FILE *fdopen(int, const char *);
int fgetchar(void);
int fileno(FILE *);
int flushall(void);
void fmode(FILE *, int);
int __stdargs _writes(char *);
int _tinyprintf(char *, ...);
int fputchar(int);
int setnbf(FILE *);
int __flushbuff(int, FILE *);
FILE *fopene(const char *, const char *,char *);
FILE *popen(const char *,const char *);
int pclose(FILE *);
extern int sys_nerr;
extern const char *sys_errlist[];
int unlink(const char *);
char *mktemp(char *s);
short fputw(int,FILE *);
long fputl(long,FILE *);
short fgetw(FILE *);
long fgetl(FILE *);
int __getbuff(FILE *);
extern int __fmask;
extern int __fmode;
extern int _bufsiz; /* default file buffer size */
/**
* $Id: stdlib.h,v 1.1 1993/11/14 14:43:52 AGK Rel $
*
* General utilities and defines
*
* (c) Copyright 1989, 1993 HiSoft
**/
typedef unsigned char wchar_t;
extern char __mb_cur_max;
typedef struct
{
int quot;
int rem;
} div_t;
typedef struct
{
long int quot;
long int rem;
} ldiv_t;
void *malloc(size_t);
void *calloc(size_t,size_t);
void *realloc(void *, size_t);
void free(void *);
void *getml(size_t);
int rlsml(void *, size_t);
size_t sizmem(void);
size_t chkml(void);
void *getmem(unsigned);
int rlsmem(void *, unsigned);
void *alloca(size_t);
extern size_t _stkdelta; /* stack/data area separation chicken factor */
void qsort(void *, size_t, size_t, int (*)(const void *, const void *));
void dqsort(double *,size_t);
void fqsort(float *,size_t);
void lqsort(long *,size_t);
void sqsort(short *,size_t);
void tqsort(char **,size_t);
int mblen(const char *,size_t);
size_t mbstowcs(wchar_t *, const char *, size_t);
int mbtowc(wchar_t *, const char *, size_t);
size_t wcstombs(char *, const wchar_t *, size_t);
int wctomb(char *, wchar_t);
void exit(int);
void abort(void);
int atoi(const char *);
double atof(const char *);
long int atol(const char *);
char *getenv(const char *);
void _exit(int);
void _XCEXIT(int);
char *argopt(int, const char *[], const char *, int *, char *);
void *bsearch(const void *, const void *, size_t, size_t, int (*)(const void *, const void *));
void *lsearch(const void *, void *, size_t *, size_t, int (*)(const void *, const void *));
void *lfind(const void *, const void *, const size_t *, size_t, int (*)(const void *, const void *));
int system(const char *);
size_t _hash(const char *);
int abs(int);
int __builtin_abs(int);
int iabs(int);
int __builtin_abs(int);
long labs(long);
long __builtin_labs(long);
int min(int,int);
int __builtin_min(int,int);
int max(int,int);
int __builtin_max(int,int);
char *ecvt(double, int, int *, int *);
char *fcvt(double, int, int *, int *);
char *gcvt(double, int, char *);
long getfnl(const char *, char *, size_t, int);
int onexit(int(*)(int));
int putenv(char *);
int rand(void);
int rmvenv(const char *);
void srand(unsigned int);
double strtod(const char *, char **);
long int strtol(const char *, char **, int);
unsigned long int strtoul(const char *,char **,int);
long int utpack(const char *);
void utunpk(long int, char *);
int atexit(void (* )(void));
div_t div(int, int);
ldiv_t ldiv(long int, long int);
unsigned long _lrotl(unsigned long,int);
unsigned short _rotl(unsigned int,int);
unsigned long _lrotr(unsigned long,int);
unsigned short _rotr(unsigned int,int);
extern char *optarg;
extern int optopt;
extern int optind;
extern int opterr;
int getopt(int, char *const *, const char *);
/* These compilers require special open modes when reading binary files.
*
* "The single most brilliant design decision in all of UNIX was the
* choice of a SINGLE character as the end-of-line indicator" -- M. O'Dell
*
* "Whoever picked the end-of-line conventions for MS-DOS and the Macintosh
* should be shot!" -- P. Karn's corollary to O'Dells' declaration
*/
/* These two lines assume that your compiler's longs are 32 bits and
* shorts are 16 bits. It is already assumed that chars are 8 bits,
* but it doesn't matter if they're signed or unsigned.
*/
typedef long int32; /* 32-bit signed integer */
typedef unsigned short int16; /* 16-bit unsigned integer */
typedef unsigned char byte_t; /* 8-bit unsigned integer */
/* The "interrupt" keyword is non-standard, so make it configurable */
/* Note that these definitions are on by default if none of the Turbo-C style
* memory model definitions are on; this avoids having to change them when
* porting to 68K environments.
*/
/* Since not all compilers support structure assignment, the ASSIGN()
* macro is used. This controls how it's actually implemented.
*/
/* Define null object pointer in case stdio.h isn't included */
/* standard boolean constants */
/* string equality shorthand */
/* Extract a short from a long */
/* Extract a byte from a short */
/* Extract nibbles from a byte */
/* Various low-level and miscellaneous functions */
unsigned long availmem (void);
void *callocw (unsigned nelem,unsigned size);
int32 clock();
int dirps (void);
int htoi (char *);
long htol (char *);
char *inbuf (int16 port,char *buf,int16 cnt);
int16 hash_ip (int32 addr);
int istate (void);
void log (int s,char *fmt, ...);
int log2 (int16 x);
void *ltop (long);
void *mallocw (unsigned nb);
char *outbuf (int16 port,char *buf,int16 cnt);
long ptol (void *);
void restore (int);
void rflush (void);
void rip (char *);
char *smsg (char *msgs[],unsigned nmsgs,unsigned n);
int tprintf (char *fmt,...);
char *strdup (const char *);
int wildmat (char *s,char *p,char **argv);
/**
* $Id: time.h,v 1.1 1993/11/14 14:43:52 AGK Rel $
*
* ANSI/POSIX.1 Date and Time definitions
*
* (c) Copyright 1993 HiSoft
**/
typedef __clock_t clock_t;
typedef __time_t time_t;
struct tm {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
clock_t (clock)(void);
double (difftime)(time_t, time_t);
time_t (mktime)(struct tm *);
time_t (time)(time_t *);
char *(asctime)(const struct tm *);
char *(ctime)(const time_t *);
struct tm *(gmtime)(const time_t *);
struct tm *(localtime)(const time_t *);
size_t (strftime)(char *, size_t, const char *, const struct tm *);
extern char *__tzname[2];
extern int __daylight;
extern long int __timezone;
void (__tzset)(void);
void (tzset)(void);
extern char *(tzname)[2];
void (getclk)(unsigned char *);
int (chgclk)(unsigned const char *);
void (utunpk)(long, char *);
long (utpack)(const char *);
int (stime)(const time_t *);
time_t ka9q_time (time_t *t);
/**
* $Id: stdlib.h,v 1.1 1993/11/14 14:43:52 AGK Rel $
*
* General utilities and defines
*
* (c) Copyright 1989, 1993 HiSoft
**/
/**
* $Id: string.h,v 1.1 1993/11/14 14:43:52 AGK Rel $
*
* String and memory operations interface file
*
* (c) Copyright 1989, 1993 HiSoft
**/
extern char _SLASH; /* path separator character */
/*
*
* External definitions for string services
*
*/
char *strcat(char *, const char *);
char *strchr(const char *, int);
int strcmp(const char *, const char *);
char *strcpy(char *, const char *);
size_t strcspn(const char *, const char *);
size_t strspn(const char *, const char *);
size_t strlen(const char *);
char *strncat(char *, const char *, size_t);
int strncmp(const char *, const char *, size_t);
char *strncpy(char *, const char *, size_t);
char *strpbrk(const char *, const char *);
char *strrchr(const char *, int);
char *strstr(const char *, const char *);
char *strtok(char *, const char *);
char *strerror(int);
int strcoll(const char *, const char *);
size_t strxfrm(char *, const char *, size_t);
size_t __builtin_strlen(const char *);
char *__builtin_strcpy(char *, const char *);
int __builtin_strcmp(const char *, const char *);
size_t stcarg(const char *, const char *);
size_t stccpy(char *to, const char *from, size_t length);
char *stpcpy(char *, const char *);
char *strdup(const char *);
void strins(char *, const char *);
char *strnset(char *, int, size_t);
char *strrev(char *);
size_t stcis(const char *, const char *);
size_t stcisn(const char *, const char *);
size_t stcpm(const char *, const char *, char **);
size_t stcpma(const char *, const char *);
char *stpblk(const char *);
char *stpbrk(const char *, const char *);
char *stpchr(const char *, int);
char *stpsym(const char *, char *, size_t);
char *stpchrn(const char *, int);
char *stptok(const char *, char *, size_t, const char *);
long strbpl(char **, size_t, const char *);
int stcgfe(char *, const char *);
int stcgfn(char *, const char *);
int stcd_i(const char *, int *);
int stcd_l(const char *, long *);
int stch_i(const char *, int *);
int stch_l(const char *, long *);
int stco_i(const char *, int *);
int stco_l(const char *, long *);
int stci_d(char *, int);
int stci_h(char *, int);
int stci_o(char *, int);
int stcl_d(char *, long);
int stcl_h(char *, long);
int stcl_o(char *, long);
int stcsma(char *, char *);
int stcu_d(char *, unsigned);
int stcul_d(char *, unsigned long);
size_t stclen(const char *);
char *stpdate(char *, int, const char *);
char *stptime(char *, int, const char *);
int strmid(const char *, char *, size_t, size_t);
char *strlwr(char *);
void strmfe(char *, const char *, const char *);
void strmfn(char *, const char *, const char *, const char *, const char *);
void strmfp(char *, const char *, const char *);
int stcgfp(char *, const char *);
int strnicmp(const char *, const char *, size_t);
int stricmp(const char *, const char *);
char *strset(char *, int);
void strsfn(const char *, char *, char *, char *, char *);
char *strupr(char *);
int stspfp(char *, int *);
void strsrt(char *[], size_t);
char *index(const char *, int);
char *rindex(const char *, int);
void swab(const void *,void *,size_t);
/*
*
* External definitions for memory block services
*
*/
void *memchr(const void *, int, size_t);
int memcmp(const void *, const void *, size_t);
void *memcpy(void *, const void *, size_t);
void *memmove(void *, const void *, size_t);
void *memset(void *, int, size_t);
void *__builtin_memset(void *, int, size_t);
int __builtin_memcmp(const void *, const void *, size_t);
void *__builtin_memcpy(void *, const void *, size_t);
void bzero(void *, size_t);
void bcopy(const void *, void *, size_t);
int bcmp(const void *, const void *, size_t);
void *memccpy(void *, const void *, int, size_t);
void *memswp(void *, void *, size_t);
void *memrep(void *, const void *, size_t, size_t);
void setmem(void *, unsigned, int);
void movmem(const void *, void *, unsigned);
void repmem(const void *, void *, unsigned, unsigned);
void swmem(void *, void *, unsigned);
/* General purpose function macros already defined in turbo C */
/* Externals used by getopt */
extern int optind;
extern char *optarg;
/* Threshold setting on available memory */
extern int32 Memthresh;
/* System clock - count of ticks since startup */
extern int32 Clock;
/* Various useful standard error messages */
extern char Badhost[];
extern char Nospace[];
extern char Notval[];
extern char *Hostname;
extern char Version[];
/* Your system's end-of-line convention */
extern char Eol[];
/* connect () failure timeout value. */
extern int32 connect_wait_val;
extern void (*Gcollect[])();
FILE *fopenx(const char *, const char *);
int removex(const char *);
int renamex(const char *, const char *);
int openx(const char *, int, int);
int creatx(const char *, int);
int unlinkx(const char *);
int accessx(const char *, int);
int mkdirx(const char *);
/**
* $Id: stdio.h,v 1.1 1993/11/14 14:43:52 AGK Rel $
*
* ANSI I/O interface file
*
* (c) Copyright 1989, 1992, 1993 HiSoft
**/
extern unsigned Ibufsize; /* Size of interrupt buffers to allocate */
extern int Nibufs; /* Number of interrupt buffers to allocate */
/* Basic message buffer structure */
struct mbuf {
struct mbuf *next; /* Links mbufs belonging to single packets */
struct mbuf *anext; /* Links packets on queues */
int16 size; /* Size of associated data buffer */
int refcnt; /* Reference count */
struct mbuf *dup; /* Pointer to duplicated mbuf */
char *data; /* Active working pointers */
int16 cnt;
};
/* In mbuf.c: */
struct mbuf *alloc_mbuf (int16 size);
struct mbuf *free_mbuf (struct mbuf *bp);
struct mbuf *ambufw (int16 size);
struct mbuf *copy_p (struct mbuf *bp,int16 cnt);
int16 dup_p (struct mbuf **hp,struct mbuf *bp,int16 offset,int16 cnt);
struct mbuf *free_p (struct mbuf *bp);
int16 len_p (struct mbuf *bp);
void trim_mbuf (struct mbuf **bpp,int16 length);
int write_p (FILE *fp,struct mbuf *bp);
struct mbuf *dequeue (struct mbuf **q);
void enqueue (struct mbuf **q,struct mbuf *bp);
void free_q (struct mbuf **q);
int16 len_q (struct mbuf *bp);
struct mbuf *qdata (char *data,int16 cnt);
int16 dqdata (struct mbuf *bp,char *buf,unsigned cnt);
void append (struct mbuf **bph,struct mbuf *bp);
struct mbuf *pushdown (struct mbuf *bp,int16 size);
int16 pullup (struct mbuf **bph,char *buf,int16 cnt);
int pullchar (struct mbuf **bpp); /* returns -1 if nothing */
long pull16 (struct mbuf **bpp); /* returns -1 if nothing */
int32 pull32 (struct mbuf **bpp); /* returns 0 if nothing */
int16 get16 (char *cp);
int32 get32 (char *cp);
char *put16 (char *cp,int16 x);
char *put32 (char *cp,int32 x);
void iqstat (void);
void refiq (void);
void mbuf_crunch (struct mbuf **bpp);
/****************************************************************************
* timer.h *
* $Id: timer.h 1.2 93/07/16 11:51:38 ROOT_DOS Exp $
* 04 Jul 93 1.2 GT Fix warnings. *
*
* ATARI Version by David Nash - dnash@chaos.demon.co.uk
*
* Adjust MSPTICK and add extern int to Tick, Cfunct
* pause -> Pause to prevent conflict with Lattice C V5.6
*
****************************************************************************/
/* Software timers
* There is one of these structures for each simulated timer.
* Whenever the timer is running, it is on a linked list
* pointed to by "Timers". The list is sorted in ascending order of
* expiration, with the first timer to expire at the head. This
* allows the timer process to avoid having to scan the entire list
* on every clock tick; once it finds an unexpired timer, it can
* stop searching.
*
* Stopping a timer or letting it expire causes it to be removed
* from the list. Starting a timer puts it on the list at the right
* place.
*/
struct timer {
struct timer *next; /* Linked-list pointer */
int32 duration; /* Duration of timer, in ticks */
int32 expiration; /* Clock time at expiration */
void (*func) (void *); /* Function to call at expiration */
void *arg; /* Arg to pass function */
char state; /* Timer state */
};
/* Useful user macros that hide the timer structure internals */
volatile extern int Tick;
extern void (*Cfunc[]) (void); /* List of clock tick functions */
/* In timer.c: */
void alarm (int32 ms);
int Pause (int32 ms);
int32 read_timer (struct timer *t);
void set_timer (struct timer *t,int32 x);
void start_timer (struct timer *t);
void stop_timer (struct timer *timer);
char *tformat (int32 t);
/* In hardware.c: */
int32 msclock (void);
int32 secclock (void);
/*
-----------------------------------------------------
ATARI Version by David Nash - dnash@chaos.demon.co.uk
hide definition of tag iface
-----------------------------------------------------
*/
/****************************************************************************
* $Id: config.h 1.5 93/07/16 11:43:29 ROOT_DOS Exp $
* 20 May 92 1.2 GT Dial up stuff only. *
* 13 Jul 93 1.3 GT Disable LZW. *
* Disable SLIP. *
****************************************************************************/
/****************************************************************************
*
* ATARI version by David Nash - dnash@chaos.demon.co.uk
*
****************************************************************************/
/* Software options */
/* Software tuning parameters */
/* Hardware driver options */
/****************************************************************************
* $Id: filter.h 1.2 93/07/16 11:44:39 ROOT_DOS Exp $
* 14 Jun 93 1.2 GT Enable ip_filter () prototype. *
*
* ATARI Version by David Nash - dnash@chaos.demon.co.uk
*
* conditionally include ip.h
*
****************************************************************************/
/*
-----------------------------------------------------
ATARI Version by David Nash - dnash@chaos.demon.co.uk
__asm added for lcsum prototype
-----------------------------------------------------
*/
/* Global structures and constants pertaining to the interface between IP and
* higher level protocols
*/
/* IP protocol field values */
/* DoD-style precedences */
/* Amateur-style precedences */
/* Class-of-service bits */
/* IP TOS fields */
/* Pseudo-header for TCP and UDP checksumming */
struct pseudo_header {
int32 source; /* IP source */
int32 dest; /* IP destination */
char protocol; /* Protocol */
int16 length; /* Data field length */
};
/* Format of a MIB entry for statistics gathering */
struct mib_entry {
char *name;
union {
int32 integer;
} value;
};
extern char Hashtab[]; /* Modulus lookup table */
/* SNMP MIB variables, used for statistics and control. See RFC 1066 */
extern struct mib_entry Ip_mib[];
/* IP header, INTERNAL representation */
struct ip {
int32 source; /* Source address */
int32 dest; /* Destination address */
int16 length; /* Total length */
int16 id; /* Identification */
int16 offset; /* Fragment offset in bytes */
int16 checksum; /* Header checksum */
struct {
char congest; /* Congestion experienced bit (exp) */
char df; /* Don't fragment flag */
char mf; /* More Fragments flag */
} flags;
char version; /* IP version number */
char tos; /* Type of service */
char ttl; /* Time to live */
char protocol; /* Protocol */
char optlen; /* Length of options field, bytes */
char options[40];/* Options field */
};
/* Fields in option type byte */
/* IP option numbers */
/* Timestamp option flags */
/* IP routing table entry */
struct route {
struct route *prev; /* Linked list pointers */
struct route *next;
int32 target; /* Target IP address */
unsigned int bits; /* Number of significant bits in target */
int32 gateway; /* IP address of local gateway for this target */
int32 metric; /* Hop count or whatever */
struct iface *iface; /* Device interface structure */
int flags;
struct timer timer; /* Time until aging of this entry */
int32 uses; /* Usage count */
};
extern struct route *Routes[32][7]; /* Routing table */
extern struct route R_default; /* Default route entry */
/* Cache for the last-used routing entry, speeds up the common case where
* we handle a burst of packets to the same destination
*/
struct rt_cache {
int32 target;
struct route *route;
};
extern struct rt_cache Rt_cache;
/* Reassembly descriptor */
struct reasm {
struct reasm *next; /* Linked list pointer */
struct timer timer; /* Reassembly timeout timer */
struct frag *fraglist; /* Head of data fragment chain */
int16 length; /* Entire datagram length, if known */
int32 source; /* src/dest/id/protocol uniquely describe a datagram */
int32 dest;
int16 id;
char protocol;
};
/* Fragment descriptor in a reassembly list */
struct frag {
struct frag *prev; /* Previous fragment on list */
struct frag *next; /* Next fragment */
struct mbuf *buf; /* Actual fragment data */
int16 offset; /* Starting offset of fragment */
int16 last; /* Ending offset of fragment */
};
extern struct reasm *Reasmq; /* The list of reassembly descriptors */
/* Structure for handling raw IP user sockets */
struct raw_ip {
struct raw_ip *next; /* Linked list pointer */
struct mbuf *rcvq; /* receive queue */
void (*r_upcall) (struct raw_ip *);
int protocol; /* Protocol */
int user; /* User linkage */
};
extern struct raw_ip *Raw_ip;
/* Transport protocol link table */
struct iplink {
char proto;
void (*funct) (struct iface *,struct ip *,struct mbuf *,int);
};
extern struct iplink Iplink[];
/* In ip.c: */
void ip_garbage (int drastic);
(struct iface *iface,struct ip *ip,struct mbuf *bp, int rxbroadcast);
(struct iface *iface,struct ip *ip,struct mbuf *bp, int rxbroadcast);
(int32 source,int32 dest,char protocol,char tos,char ttl, struct mbuf *bp,int16 length,int16 id,char df);
struct raw_ip *raw_ip (int protocol,void (*r_upcall) (struct raw_ip *) );
void del_ip (struct raw_ip *rrp);
/* In iproute.c: */
void ipinit (void);
int16 ip_mtu (int32 addr);
(struct mbuf *bp,struct iface *iface,int32 gateway, int prec,int del,int tput,int rel);
int ip_route (struct iface *i_iface,struct mbuf *bp,int rxbroadcast);
int32 locaddr (int32 addr);
void rt_merge (int trace);
(int32 target,unsigned int bits,int32 gateway, struct iface *iface,int32 metric,int32 ttl,char private);
int rt_drop (int32 target,unsigned int bits);
struct route *rt_lookup (int32 target);
struct route *rt_blookup (int32 target,unsigned int bits);
/* In iphdr.c: */
int16 cksum (struct pseudo_header *ph,struct mbuf *m,int16 len);
int16 eac (int32 sum);
struct mbuf *htonip (struct ip *ip,struct mbuf *data,int cflag);
int ntohip (struct ip *ip,struct mbuf **bpp);
/* In either lcsum.c or pcgen.asm: */
int16 __asm lcsum(int16 *wp, int16 len);
/*
* Filter entry structure.
*/
struct filter {
struct filter *next; /* Link to next filter element */
short action; /* Filter entry match action */
int (*type) (struct mbuf *bp, struct ip *ip, struct filter *fp); /* Packet type comparison f(x) */
struct filtersd {
unsigned long addr; /* Address used for comparisons */
unsigned long mask; /* Address comparison mask */
unsigned char bits; /* One bits in high part of mask*/
unsigned char exclude; /* Exclude matching addresses */
unsigned short port; /* TCP/UDP port (low of range) */
unsigned short hiport; /* High port of range */
} src, dest;
unsigned long matches; /* Number of matching packets */
};
int doipfilter ( int argc, char *argv[], void *p );
int ip_filter ( struct mbuf *bp, struct ip *ip, struct filter *fp );
/**
* $Id: setjmp.h,v 1.2 1993/11/14 14:43:52 AGK Rel $
*
* ANSI/POSIX.1 non-local jumps
*
* (c) Copyright 1992, 1993 HiSoft
**/
typedef struct {long __jmp_buf[13];} jmp_buf[1];
void (longjmp)(jmp_buf,int);
int (setjmp)(jmp_buf);
typedef struct {long __sigjmp_buf[13 + (sizeof(__sigset_t) / sizeof(long))];} sigjmp_buf[1];
void (siglongjmp)(sigjmp_buf, int);
int (sigsetjmp)(sigjmp_buf, int);
/* Kernel process control block */
struct proc {
struct proc *prev; /* Process table pointers */
struct proc *next;
jmp_buf env; /* Process state */
char i_state; /* Process interrupt state */
unsigned short state;
void *event; /* Wait event */
int16 *stack; /* Process stack */
unsigned stksize; /* Size of same */
char *name; /* Arbitrary user-assigned name */
int retval; /* Return value from next pwait() */
struct timer alarm; /* Alarm clock timer */
struct mbuf *outbuf; /* Terminal output buffer */
int input; /* standard input socket */
int output; /* standard output socket */
int iarg; /* Copy of iarg */
void *parg1; /* Copy of parg1 */
void *parg2; /* Copy of parg2 */
int freeargs; /* Free args on termination if set */
};
extern struct proc *Waittab[]; /* Head of wait list */
extern struct proc *Rdytab; /* Head of ready list */
extern struct proc *Curproc; /* Currently running process */
extern struct proc *Susptab; /* Suspended processes */
extern int Stkchk; /* Stack checking flag */
/* In kernel.c: */
void alert (struct proc *pp,int val);
void chname (struct proc *pp,char *newname);
void killproc (struct proc *pp);
void killself (void);
struct proc *mainproc (char *name);
(char *name,unsigned int stksize, void (*pc) (int,void *,void *), int iarg,void *parg1,void *parg2,int freeargs);
int psignal (void *event,int n);
int pwait (void *event);
void resume (struct proc *pp);
void suspend (struct proc *pp);
/* In ksubr.c: */
void chkstk (void);
void kinit (void);
unsigned phash (void *event);
(struct proc *pp,int iarg,void *parg1,void *parg2, void ((*pc) (int,void *,void *) ) );
/* Stack background fill value for high water mark checking */
/* Value stashed in location 0 to detect null pointer dereferences */
/* Interface encapsulation mode table entry. An array of these structures
* are initialized in config.c with all of the information necessary
* to attach a device.
*/
struct iface; /* ATARI incomplete definition to hide definition of tag iface */
struct iftype {
char *name; /* Name of encapsulation technique */
int (*send) (struct mbuf *,struct iface *,int32,int,int,int,int);
/* Routine to send an IP datagram */
int (*output) (struct iface *,char *,char *,int16,struct mbuf *);
/* Routine to send link packet */
char *(*format) (char *,char *);
/* Function that formats addresses */
int (*scan) (char *,char *);
/* Reverse of format */
int type; /* Type field for network process */
int hwalen; /* Length of hardware address, if any */
};
extern struct iftype Iftypes[];
/* Interface control structure */
struct iface {
struct iface *next; /* Linked list pointer */
char *name; /* Ascii string with interface name */
int32 addr; /* IP address */
int32 broadcast; /* Broadcast address */
int32 netmask; /* Network mask */
int16 mtu; /* Maximum transmission unit size */
int16 flags; /* Configuration flags */
int16 trace; /* Trace flags */
char *trfile; /* Trace file name, if any */
FILE *trfp; /* Stream to trace to */
struct iface *forw; /* Forwarding interface for output, if rx only */
struct proc *rxproc; /* Receiver process, if any */
struct proc *txproc; /* Transmitter process, if any */
struct proc *supv; /* Supervisory process, if any */
/* Filter specifications */
struct filter *infilter; /* Inbound filter */
struct filter *outfilter; /* Outbound filter */
/* Device dependant */
int dev; /* Subdevice number to pass to send */
/* To device -- control */
int32 (*ioctl) (struct iface *,int cmd,int set,int32 val);
/* From device -- when status changes */
int (*iostatus) (struct iface *,int cmd,int32 val);
/* Call before detaching */
int (*stop) (struct iface *);
char *hwaddr; /* Device hardware address, if any */
/* Encapsulation dependant */
void *edv; /* Pointer to protocol extension block, if any */
int type; /* Link header type for phdr */
int xdev; /* Associated Slip or Nrs channel, if any */
struct iftype *iftype; /* Pointer to appropriate iftype entry */
/* Encapsulate an IP datagram */
int (*send) (struct mbuf *,struct iface *,int32,int,int,int,int);
/* Encapsulate any link packet */
int (*output) (struct iface *,char *,char *,int16,struct mbuf *);
/* Send raw packet */
int (*raw) (struct iface *,struct mbuf *);
/* Display status */
void (*show) (struct iface *);
int (*discard) (struct iface *,struct mbuf *);
int (*echo) (struct iface *,struct mbuf *);
/* Counters */
int32 ipsndcnt; /* IP datagrams sent */
int32 rawsndcnt; /* Raw packets sent */
int32 iprecvcnt; /* IP datagrams received */
int32 rawrecvcnt; /* Raw packets received */
int32 lastsent; /* Clock time of last send */
int32 lastrecv; /* Clock time of last receive */
/* Demand dial */
int dial_me; /* !0 means demand dial */
};
extern struct iface *Ifaces; /* Head of interface list */
extern struct iface Loopback; /* Optional loopback interface */
extern struct iface Encap; /* IP-in-IP pseudo interface */
/* Header put on front of each packet in input queue */
struct phdr {
struct iface *iface;
unsigned short type; /* Use pktdrvr "class" values */
};
extern char Noipaddr[];
extern struct mbuf *Hopper;
/* In iface.c: */
struct iface *if_lookup (char *name);
struct iface *ismyaddr (int32 addr);
int if_detach (struct iface *ifp);
int setencap (struct iface *ifp,char *mode);
char *if_name (struct iface *ifp,char *comment);
int bitbucket (struct iface *ifp,struct mbuf *bp);
/* In config.c: */
int net_route (struct iface *ifp,int type,struct mbuf *bp);
/* Generic Ethernet constants and templates */
/* Format of an Ethernet header */
struct ether {
char dest[6];
char source[6];
int16 type;
};
/* Ethernet broadcast address */
extern char Ether_bdcst[];
/* Ethernet type fields */
/* In file enet.c: */
char *pether (char *out,char *addr);
int gether (char *out,char *cp);
(struct mbuf *bp,struct iface *iface,int32 gateway,int prec, int del,int tput,int rel);
(struct iface *iface,char dest[],char source[],int16 type, struct mbuf *data);
void eproc (struct iface *iface,struct mbuf *bp);
/* In enethdr.c: */
struct mbuf *htonether (struct ether *ether,struct mbuf *data);
int ntohether (struct ether *ether,struct mbuf **bpp);
/* Berkeley format socket address structures. These things were rather
* poorly thought out, but compatibility is important (or so they say).
* Note that all the sockaddr variants must be of the same size, 16 bytes
* to be specific. Although attempts have been made to account for alignment
* requirements (notably in sockaddr_ax), porters should check each
* structure.
*/
/* Generic socket address structure */
struct sockaddr {
short sa_family;
char sa_data[14];
};
/* This is a structure for "historical" reasons (whatever they are) */
struct in_addr {
unsigned long s_addr;
};
/* Socket address, DARPA Internet style */
struct sockaddr_in {
short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
/* AX.25 datagram (address) sub-layer definitions */
/* Upper sub-layer (LAPB) definitions */
/* Control field templates */
/* FRMR reason bits */
/* Per-connection link control block
* These are created and destroyed dynamically,
* and are indexed through a hash table.
* One exists for each logical AX.25 Level 2 connection
*/
struct ax25_cb {
struct ax25_cb *next; /* Linked list pointer */
struct iface *iface; /* Interface */
struct mbuf *txq; /* Transmit queue */
struct mbuf *rxasm; /* Receive reassembly buffer */
struct mbuf *rxq; /* Receive queue */
char local[7]; /* Addresses */
char remote[7];
struct {
char rejsent; /* REJ frame has been sent */
char remotebusy; /* Remote sent RNR */
char rtt_run; /* Round trip "timer" is running */
char retrans; /* A retransmission has occurred */
char clone; /* Server-type cb, will be cloned */
} flags;
char reason; /* Reason for connection closing */
char response; /* Response owed to other end */
char vs; /* Our send state variable */
char vr; /* Our receive state variable */
char unack; /* Number of unacked frames */
int maxframe; /* Transmit flow control level, frames */
int16 paclen; /* Maximum outbound packet size, bytes */
int16 window; /* Local flow control limit, bytes */
char proto; /* Protocol version */
int16 pthresh; /* Poll threshold, bytes */
unsigned retries; /* Retry counter */
unsigned n2; /* Retry limit */
int state; /* Link state */
struct timer t1; /* Retry timer */
struct timer t3; /* Keep-alive poll timer */
int32 rtt_time; /* Stored clock values for RTT, ticks */
int rtt_seq; /* Sequence number being timed */
int32 srt; /* Smoothed round-trip time, ms */
int32 mdev; /* Mean rtt deviation, ms */
void (*r_upcall) (struct ax25_cb *,int); /* Receiver upcall */
void (*t_upcall) (struct ax25_cb *,int); /* Transmit upcall */
void (*s_upcall) (struct ax25_cb *,int,int); /* State change upcall */
int user; /* User pointer */
int segremain; /* Segmenter state */
};
extern struct ax25_cb Ax25default,*Ax25_cb;
extern char *Ax25states[],*Axreasons[];
extern int32 Axirtt,T3init,Blimit;
extern int16 N2,Maxframe,Paclen,Pthresh,Axwindow,Axversion;
/* In lapb.c: */
void est_link (struct ax25_cb *axp);
void lapbstate (struct ax25_cb *axp,int s);
int lapb_input (struct ax25_cb *axp,int cmdrsp,struct mbuf *bp);
int lapb_output (struct ax25_cb *axp);
struct mbuf *segmenter (struct mbuf *bp,int16 ssize);
int sendctl (struct ax25_cb *axp,int cmdrsp,int cmd);
/* In lapbtimer.c: */
void pollthem (void *p);
void recover (void *p);
/* In ax25subr.c: */
int16 ftype (int control);
void lapb_garbage (int drastic);
/* Bits within SSID field of AX.25 address */
/* Our AX.25 address */
extern char Mycall[7];
/* List of AX.25 multicast addresses, e.g., "QST -0" in shifted ASCII */
extern char Ax25multi[][7];
extern int Digipeat;
extern int Ax25mbox;
/* Number of chars in interface field. The involved definition takes possible
* alignment requirements into account, since ax25_addr is of an odd size.
*/
/* Socket address, AX.25 style */
struct sockaddr_ax {
short sax_family; /* 2 bytes */
char ax25_addr[7];
char iface[(sizeof(struct sockaddr) - sizeof(short) - 7)]; /* Interface name */
};
/* Internal representation of an AX.25 header */
struct ax25 {
char dest[7]; /* Destination address */
char source[7]; /* Source address */
char digis[7][7]; /* Digi string */
int ndigis; /* Number of digipeaters */
int nextdigi; /* Index to next digi in chain */
int cmdrsp; /* Command/response */
};
/* C-bit stuff */
/* AX.25 routing table entry */
struct ax_route {
struct ax_route *next; /* Linked list pointer */
char target[7];
char digis[7][7];
int ndigis;
char type;
};
extern struct ax_route *Ax_routes;
extern struct ax_route Ax_default;
/* AX.25 Level 3 Protocol IDs (PIDs) */
/* Link quality report packet header, internal format */
struct lqhdr {
int16 version; /* Version number of protocol */
int32 ip_addr; /* Sending station's IP address */
};
/* Link quality entry, internal format */
struct lqentry {
char addr[7]; /* Address of heard station */
int32 count; /* Count of packets heard from that station */
};
/* Link quality database record format
* Currently used only by AX.25 interfaces
*/
struct lq {
struct lq *next;
char addr[7]; /* Hardware address of station heard */
struct iface *iface; /* Interface address was heard on */
int32 ka9q_time; /* Time station was last heard */
int32 currxcnt; /* Current # of packets heard from this station */
};
extern struct lq *Lq; /* Link quality record headers */
/* Structure used to keep track of monitored destination addresses */
struct ld {
struct ld *next; /* Linked list pointers */
char addr[7];/* Hardware address of destination overheard */
struct iface *iface; /* Interface address was heard on */
int32 ka9q_time; /* Time station was last mentioned */
int32 currxcnt; /* Current # of packets destined to this station */
};
extern struct ld *Ld; /* Destination address record headers */
/* Linkage to network protocols atop ax25 */
struct axlink {
int pid;
(struct iface *,struct ax25_cb *,char *, char *, struct mbuf *,int);
};
extern struct axlink Axlink[];
/* Codes for the open_ax25 call */
/* In ax25.c: */
struct ax_route *ax_add (char *,int,char digis[][7],int);
int ax_drop (char *);
struct ax_route *ax_lookup (char *);
void ax_recv (struct iface *,struct mbuf *);
(struct mbuf *bp,struct iface *iface,int32 gateway,int prec, int del,int tput,int rel);
(struct iface *iface,char *dest,char *source,int16 pid, struct mbuf *data);
int sendframe (struct ax25_cb *axp,int cmdrsp,int ctl,struct mbuf *data);
(struct iface *iface,struct ax25_cb *axp,char *src, char *dest,struct mbuf *bp,int mcast);
/* In ax25cmd.c: */
void st_ax25 (struct ax25_cb *axp);
/* In axhdr.c: */
struct mbuf *htonax25 (struct ax25 *hdr,struct mbuf *data);
int ntohax25 (struct ax25 *hdr,struct mbuf **bpp);
/* In axlink.c: */
void getlqentry (struct lqentry *ep,struct mbuf **bpp);
void getlqhdr (struct lqhdr *hp,struct mbuf **bpp);
void logsrc (struct iface *iface,char *addr);
void logdest (struct iface *iface,char *addr);
char *putlqentry (char *cp,char *addr,int32 count);
char *putlqhdr (char *cp,int16 version,int32 ip_addr);
struct lq *al_lookup (struct iface *ifp,char *addr,int sort);
/* In ax25user.c: */
(struct iface *,char *,char *, int,int16, void (*) (struct ax25_cb *,int), void (*) (struct ax25_cb *,int), void (*) (struct ax25_cb *,int,int), int user);
struct mbuf *recv_ax25 (struct ax25_cb *axp,int16 cnt);
int reset_ax25 (struct ax25_cb *axp);
int send_ax25 (struct ax25_cb *axp,struct mbuf *bp,int pid);
/* In ax25subr.c: */
int addreq (char *a,char *b);
struct ax25_cb *cr_ax25 (char *addr);
void del_ax25 (struct ax25_cb *axp);
struct ax25_cb *find_ax25 (char *);
char *pax25 (char *e,char *addr);
int setcall (char *out,char *call);
/* In socket.c: */
void beac_input (struct iface *iface,char *src,struct mbuf *bp);
void s_arcall (struct ax25_cb *axp,int cnt);
void s_ascall (struct ax25_cb *axp,int old,int new);
void s_atcall (struct ax25_cb *axp,int cnt);
/*
-----------------------------------------------------
ATARI Version by David Nash - dnash@chaos.demon.co.uk
Added #define POST and __stdargs upload
-----------------------------------------------------
*/
/**
* $Id: stdio.h,v 1.1 1993/11/14 14:43:52 AGK Rel $
*
* ANSI I/O interface file
*
* (c) Copyright 1989, 1992, 1993 HiSoft
**/
/****************************************************************************
* $Id: hardware.h 1.3 93/07/16 11:45:05 ROOT_DOS Exp $
* 15 Jul 93 1.2 GT Fix warnings. *
****************************************************************************/
struct stopwatch {
long calls;
int16 maxval;
int16 minval;
};
struct screen {
char *save; /* Screen save buffer */
int row; /* Saved cursor location */
int col;
};
extern struct stopwatch Sw[];
extern int16 Intstk[]; /* Interrupt stack defined in pcgen.asm */
extern void (*Shutdown[])(); /* List of functions to call at shutdown */
extern int Mtasker; /* Type of multitasker, if any */
/* In 8250.c: */
void asytimer (void);
/* In scc.c: */
void scctimer (void);
void sccstop (void);
/* In pc.c: */
void newscreen (struct session *sp);
void freescreen (struct session *sp);
long bioscnt (void);
void clrbit (unsigned port,char bits);
void ctick (void);
int32 divrem (int32 dividend,int16 divisor);
void (*getirq (unsigned int) ) (void);
int getmask (unsigned irq);
void ioinit (void);
void iostop (void);
void kbint (void);
int kbread (void);
int maskoff (unsigned irq);
int maskon (unsigned irq);
void pctick (void);
void setbit (unsigned port,char bits);
int setirq (unsigned irq,void (*handler) (void));
void sysreset (void);
void systick (void);
void writebit (unsigned port,char mask,int val);
/* In pcgen.asm: */
void btick (void);
void chktasker (void);
void chtimer (void (*)());
int32 divrem (int32 dividend,int16 divisor);
int16 getss (void);
void giveup (void);
int kbraw (void);
int16 longdiv (int16 divisor,int n,int16 *dividend);
int16 longmul (int16 multiplier,int n,int16 *multiplicand);
void nullvec (void);
void uchtimer (void);
int16 clockbits (void);
/* In stopwatch.asm: */
void swstart (void);
int16 stopval (void);
/* In sw.c: */
void swstop (int n);
/*
-----------------------------------------------------
ATARI Version by David Nash - dnash@chaos.demon.co.uk
Added V_BYTE verbosity level
-----------------------------------------------------
*/
/**
* $Id: stdio.h,v 1.1 1993/11/14 14:43:52 AGK Rel $
*
* ANSI I/O interface file
*
* (c) Copyright 1989, 1992, 1993 HiSoft
**/
/* Definitions common to both FTP servers and clients */
/* In ftpsubr.c: */
long sendfile (FILE *fp,int s,int mode,int hash);
long recvfile (FILE *fp,int s,int mode,int hash);
int isbinary (FILE *fp);
/* Per-session FTP client control block */
struct ftpcli {
int control; /* Control socket */
int data; /* Data socket */
char state;
int16 verbose; /* Transfer verbosity level */
int batch; /* Command batching flag */
int abort; /* Aborted transfer flag */
char type; /* Transfer type */
char typesent; /* Last type command sent to server */
int logbsize; /* Logical byte size for logical type */
FILE *fp; /* File descriptor being transferred */
struct session *session;
};
/*
-----------------------------------------------------
ATARI Version by David Nash - dnash@chaos.demon.co.uk
Added __stdargs to tel_output and ttylhandle
-----------------------------------------------------
*/
/* Telnet command characters */
/* Telnet options */
/* Telnet protocol control block */
struct telnet {
char local[6]; /* Local option settings */
char remote[6]; /* Remote option settings */
struct session *session; /* Pointer to session structure */
char eolmode; /* Control translation of enter key */
};
extern int Refuse_echo;
extern int Tn_cr_mode;
/* In telnet.c: */
int tel_connect (struct session *sp,char *fsocket,int len);
void __stdargs tel_output (int unused, void *p1, void *p2);
void tnrecv (struct telnet *tn);
void doopt (struct telnet *tn,int opt);
void dontopt (struct telnet *tn,int opt);
void willopt (struct telnet *tn,int opt);
void wontopt (struct telnet *tn,int opt);
void answer (struct telnet *tn,int r1,int r2);
/* In ttylink.c: */
void __stdargs ttylhandle(int s, void *unused, void *p);
struct ttystate {
struct mbuf *line; /* Line buffer */
int echo; /* Keyboard local echoing? */
int edit; /* Local editing? */
int crnl; /* Translate cr to lf? */
};
/* Session control structure; only one entry is used at a time */
struct session {
int type;
char *name; /* Name of remote host */
union {
struct ftpcli *ftp;
struct telnet *telnet;
} cb;
struct proc *proc; /* Primary session process (e.g., tn recv) */
struct proc *proc1; /* Secondary session process (e.g., tn xmit) */
struct proc *proc2; /* Tertiary session process (e.g., upload) */
int s; /* Primary network socket (control for FTP) */
FILE *record; /* Receive record file */
char *rfile; /* Record file name */
FILE *upload; /* Send file */
char *ufile; /* Upload file name */
struct ttystate ttystate;
struct screen *screen;
int input; /* Input socket */
int output; /* Output socket */
int flowmode; /* control "more" mode */
int row; /* Rows remaining until "more" */
int morewait; /* Output driver is waiting on us */
int cur_pos; /* Cursor position within input buffer */
};
extern char *Sestypes[];
extern unsigned Nsessions; /* Maximum number of sessions */
extern struct session *Sessions; /* Session descriptors themselves */
extern struct session *Current; /* Always points to current session */
extern struct session *Lastcurr; /* Last non-command session */
extern struct session *Command; /* Pointer to command session */
/* In session.c: */
void freesession (struct session *sp);
struct session *sessptr (char *cp);
struct session *newsession (char *name,int type);
void __stdargs upload(int unused, void *sp1, void *p);
/* In pc.c: */
void swapscreen (struct session *old,struct session *new);
extern int16 Lport;
/* SNMP MIB variables, used for statistics and control. See RFC 1066 */
extern struct mib_entry Icmp_mib[];
/* Internet Control Message Protocol */
/* Message types */
/* Internal format of an ICMP header (checksum is missing) */
struct icmp {
char type;
char code;
union icmp_args {
int16 mtu;
int32 unused;
unsigned char pointer;
int32 address;
struct {
int16 id;
int16 seq;
} echo;
} args;
};
/* Destination Unreachable codes */
/* Time Exceeded codes */
/* Redirect message codes */
extern int Icmp_trace;
struct ping {
struct session *sp;
int32 target; /* Starting target IP address */
int incflag; /* If true, increment target after each ping */
int32 sent; /* Total number of pings sent */
int32 srtt; /* Smoothed round trip time */
int32 mdev; /* Mean deviation */
int32 responses; /* Total number of responses */
int32 interval; /* Inter-ping interval, ticks */
int16 len; /* Length of data portion of ping */
};
/* ICMP messages, decoded */
extern char *Icmptypes[],*Unreach[],*Exceed[],*Redirect[];
struct icmplink {
char proto;
void (*funct) (int32,int32,int32,char,char,struct mbuf **);
};
extern struct icmplink Icmplink[];
/* In icmp.c: */
(struct iface *iface,struct ip *ip,struct mbuf *bp, int rxbroadcast);
(struct ip *ip,struct mbuf *data,char type,char code, union icmp_args *args);
/* In icmpcmd.c: */
void echo_proc (int32 source,int32 dest,struct icmp *icmp,struct mbuf *bp);
int pingem (int s,int32 target,int16 seq,int16 id,int16 len);
/* In icmphdr.c: */
struct mbuf *htonicmp (struct icmp *icmp,struct mbuf *data);
int ntohicmp (struct icmp *icmp,struct mbuf **bpp);
/*
-----------------------------------------------------
ATARI Version by David Nash - dnash@chaos.demon.co.uk
__asm added for lcsum prototype
-----------------------------------------------------
*/
/* Lifetime of a valid ARP entry */
/* Lifetime of a pending ARP entry */
/* ARP definitions (see RFC 826) */
/* Address size definitions */
/* ARP opcodes */
/* Hardware types */
extern char *Arptypes[]; /* Type fields in ASCII, defined in arpcmd */
/* Table of hardware types known to ARP */
struct arp_type {
int16 hwalen; /* Hardware length */
int16 iptype; /* Hardware type field for IP */
int16 arptype; /* Hardware type field for ARP */
int16 pendtime; /* # secs to wait pending response */
char *bdcst; /* Hardware broadcast address */
char *(*format) (char *,char *);
/* Function that formats addresses */
int (*scan) (char *,char *);
/* Reverse of format */
};
extern struct arp_type Arp_type[];
/* Format of an ARP request or reply packet. From p. 3 */
struct arp {
int16 hardware; /* Hardware type */
int16 protocol; /* Protocol type */
char hwalen; /* Hardware address length, bytes */
char pralen; /* Length of protocol address */
int16 opcode; /* ARP opcode (request/reply) */
char shwaddr[255]; /* Sender hardware address field */
int32 sprotaddr; /* Sender Protocol address field */
char thwaddr[255]; /* Target hardware address field */
int32 tprotaddr; /* Target protocol address field */
};
/* Format of ARP table */
struct arp_tab {
struct arp_tab *next; /* Doubly-linked list pointers */
struct arp_tab *prev;
struct timer timer; /* Time until aging this entry */
struct mbuf *pending; /* Queue of datagrams awaiting resolution */
int32 ip_addr; /* IP Address, host order */
int16 hardware; /* Hardware type */
char state; /* (In)complete */
char pub; /* Respond to requests for this entry? */
char *hw_addr; /* Hardware address */
};
extern struct arp_tab *Arp_tab[];
struct arp_stat {
unsigned recv; /* Total number of ARP packets received */
unsigned badtype; /* Incoming requests for unsupported hardware */
unsigned badlen; /* Incoming length field(s) didn't match types */
unsigned badaddr; /* Bogus incoming addresses */
unsigned inreq; /* Incoming requests for us */
unsigned replies; /* Replies sent */
unsigned outreq; /* Outoging requests sent */
};
extern struct arp_stat Arp_stat;
/* In arp.c: */
(int32 ipaddr,int16 hardware,char *hw_addr, int pub);
void arp_drop (void *p);
(unsigned int hwtype,int hwalen,int iptype,int arptype, int pendtime,char *bdcst,char *(*format) (char *,char *), int (*scan) (char *,char *) );
void arp_input (struct iface *iface,struct mbuf *bp);
struct arp_tab *arp_lookup (int16 hardware,int32 ipaddr);
char *res_arp (struct iface *iface,int16 hardware,int32 target,struct mbuf *bp);
/* In arphdr.c: */
struct mbuf *htonarp (struct arp *arp);
int ntoharp (struct arp *arp,struct mbuf **bpp);
static void arp_output (struct iface *iface,int16 hardware,int32 target);
/* Hash table headers */
struct arp_tab *Arp_tab[7];
struct arp_stat Arp_stat;
/* Resolve an IP address to a hardware address; if not found,
* initiate query and return NULLCHAR. If an address is returned, the
* interface driver may send the packet; if NULLCHAR is returned,
* res_arp() will have saved the packet on its pending queue,
* so no further action (like freeing the packet) is necessary.
*/
char *res_arp(
struct iface *iface, /* Pointer to interface block */
int16 hardware, /* Hardware type */
int32 target, /* Target IP address */
struct mbuf *bp) /* IP datagram to be queued if unresolved */
{
register struct arp_tab *arp;
struct ip ip;
if((arp = arp_lookup(hardware,target)) != (struct arp_tab *)0 && arp->state == 1)
return arp->hw_addr;
if(arp != (struct arp_tab *)0){
/* Earlier packets are already pending, kick this one back
* as a source quench
*/
ntohip(&ip,&bp);
icmp_output(&ip,bp,4,0,((void *) 0));
free_p(bp);
} else {
/* Create an entry and put the datagram on the
* queue pending an answer
*/
arp = arp_add(target,hardware,(char *)0,0);
enqueue(&arp->pending,bp);
arp_output(iface,hardware,target);
}
return (char *)0;
}
/* Handle incoming ARP packets. This is almost a direct implementation of
* the algorithm on page 5 of RFC 826, except for:
* 1. Outgoing datagrams to unresolved addresses are kept on a queue
* pending a reply to our ARP request.
* 2. The names of the fields in the ARP packet were made more mnemonic.
* 3. Requests for IP addresses listed in our table as "published" are
* responded to, even if the address is not our own.
*/
void
arp_input(iface,bp)
struct iface *iface;
struct mbuf *bp;
{
struct arp arp;
struct arp_tab *ap;
struct arp_type *at;
int i;
Arp_stat.recv++;
if(ntoharp(&arp,&bp) == -1) /* Convert into host format */
return;
if(arp.hardware >= 9){
/* Unknown hardware type, ignore */
Arp_stat.badtype++;
return;
}
at = &Arp_type[arp.hardware];
if(arp.protocol != at->iptype){
/* Unsupported protocol type, ignore */
Arp_stat.badtype++;
return;
}
if(/*uchar(arp.hwalen) > MAXHWALEN ||*/ ((unsigned char)(arp.pralen)) != sizeof(int32)){
/* Incorrect protocol addr length (different hw addr lengths
* are OK since AX.25 addresses can be of variable length)
*/
Arp_stat.badlen++;
return;
}
if(__builtin_memcmp(arp.shwaddr,at->bdcst,at->hwalen) == 0){
/* This guy is trying to say he's got the broadcast address! */
Arp_stat.badaddr++;
return;
}
/* If this guy is already in the table, update its entry
* unless it's a manual entry (noted by the lack of a timer)
*/
ap = (struct arp_tab *)0; /* ap plays the role of merge_flag in the spec */
if((ap = arp_lookup(arp.hardware,arp.sprotaddr)) != (struct arp_tab *)0
&& ((&ap->timer)->duration* 20) != 0){
ap = arp_add(arp.sprotaddr,arp.hardware,arp.shwaddr,0);
}
/* See if we're the address they're looking for */
if(ismyaddr(arp.tprotaddr) != (struct iface *)0){
if(ap == (struct arp_tab *)0) /* Only if not already in the table */
arp_add(arp.sprotaddr,arp.hardware,arp.shwaddr,0);
if(arp.opcode == 1){
/* Swap sender's and target's (us) hardware and protocol
* fields, and send the packet back as a reply
*/
__builtin_memcpy(arp.thwaddr,arp.shwaddr,(int16)((unsigned char)(arp.hwalen)));
/* Mark the end of the sender's AX.25 address
* in case he didn't
*/
if(arp.hardware == 3)
arp.thwaddr[((unsigned char)(arp.hwalen))-1] |= 0x01;
__builtin_memcpy(arp.shwaddr,iface->hwaddr,at->hwalen);
arp.tprotaddr = arp.sprotaddr;
arp.sprotaddr = iface->addr;
arp.opcode = 2;
if((bp = htonarp(&arp)) == (struct mbuf *)0)
return;
if(iface->forw != (struct iface *)0)
(*iface->forw->output)(iface->forw,
arp.thwaddr,iface->forw->hwaddr,at->arptype,bp);
else
(*iface->output)(iface,arp.thwaddr,
iface->hwaddr,at->arptype,bp);
Arp_stat.inreq++;
} else {
Arp_stat.replies++;
}
} else if(arp.opcode == 1
&& (ap = arp_lookup(arp.hardware,arp.tprotaddr)) != (struct arp_tab *)0
&& ap->pub){
/* Otherwise, respond if the guy he's looking for is
* published in our table.
*/
__builtin_memcpy(arp.thwaddr,arp.shwaddr,(int16)((unsigned char)(arp.hwalen)));
__builtin_memcpy(arp.shwaddr,ap->hw_addr,at->hwalen);
arp.tprotaddr = arp.sprotaddr;
arp.sprotaddr = ap->ip_addr;
arp.opcode = 2;
if((bp = htonarp(&arp)) == (struct mbuf *)0)
return;
if(iface->forw != (struct iface *)0)
(*iface->forw->output)(iface->forw,
arp.thwaddr,iface->forw->hwaddr,at->arptype,bp);
else
(*iface->output)(iface,arp.thwaddr,
iface->hwaddr,at->arptype,bp);
Arp_stat.inreq++;
} else if(arp.opcode == 3){
for(i=0;i< 7;i++)
for(ap = Arp_tab[i];ap != (struct arp_tab *)0;ap = ap->next)
if(__builtin_memcmp(ap->hw_addr,arp.thwaddr,at->hwalen) == 0)
goto found;
found: if(ap != (struct arp_tab *)0 && ap->pub){
__builtin_memcpy(arp.shwaddr,iface->hwaddr,at->hwalen);
arp.tprotaddr = ap->ip_addr;
arp.sprotaddr = iface->addr;
arp.opcode = 4;
if((bp = htonarp(&arp)) == (struct mbuf *)0)
return;
if(iface->forw != (struct iface *)0)
(*iface->forw->output)(iface->forw,
arp.thwaddr,iface->forw->hwaddr,0x8035,bp);
else
(*iface->output)(iface,arp.thwaddr,
iface->hwaddr,0x8035,bp);
Arp_stat.inreq++;
}
}
}
/* Add an IP-addr / hardware-addr pair to the ARP table */
struct arp_tab *arp_add(
int32 ipaddr, /* IP address, host order */
int16 hardware, /* Hardware type */
char *hw_addr, /* Hardware address, if known; NULLCHAR otherwise */
int pub) /* Publish this entry? */
{
struct mbuf *bp;
register struct arp_tab *ap;
struct arp_type *at;
unsigned hashval;
if(hardware >= 9)
return (struct arp_tab *)0; /* Invalid hardware type */
at = &Arp_type[hardware];
if((ap = arp_lookup(hardware,ipaddr)) == (struct arp_tab *)0){
/* New entry */
ap = (struct arp_tab *)callocw(1,sizeof(struct arp_tab));
ap->hw_addr = mallocw(at->hwalen);
ap->timer.func = arp_drop;
ap->timer.arg = ap;
ap->hardware = hardware;
ap->ip_addr = ipaddr;
/* Put on head of hash chain */
hashval = hash_ip(ipaddr);
ap->prev = (struct arp_tab *)0;
ap->next = Arp_tab[hashval];
Arp_tab[hashval] = ap;
if(ap->next != (struct arp_tab *)0){
ap->next->prev = ap;
}
}
if(hw_addr == (char *)0){
/* Await response */
ap->state = 0;
set_timer(&ap->timer,Arp_type[hardware].pendtime * 1000L);
} else {
/* Response has come in, update entry and run through queue */
ap->state = 1;
set_timer(&ap->timer,900 *1000L);
__builtin_memcpy(ap->hw_addr,hw_addr,at->hwalen);
ap->pub = pub;
while((bp = dequeue(&ap->pending)) != (struct mbuf *)0)
ip_route((struct iface *)0,bp,0);
}
start_timer(&ap->timer);
return ap;
}
/* Remove an entry from the ARP table */
void
arp_drop(p)
void *p;
{
register struct arp_tab *ap;
ap = (struct arp_tab *)p;
if(ap == (struct arp_tab *)0)
return;
stop_timer(&ap->timer); /* Shouldn't be necessary */
if(ap->next != (struct arp_tab *)0)
ap->next->prev = ap->prev;
if(ap->prev != (struct arp_tab *)0)
ap->prev->next = ap->next;
else
Arp_tab[hash_ip(ap->ip_addr)] = ap->next;
free_q(&ap->pending);
free(ap->hw_addr);
free((char *)ap);
}
/* Look up the given IP address in the ARP table */
struct arp_tab * arp_lookup(
int16 hardware,
int32 ipaddr)
{
register struct arp_tab *ap;
for(ap = Arp_tab[hash_ip(ipaddr)]; ap != (struct arp_tab *)0; ap = ap->next){
if(ap->ip_addr == ipaddr && ap->hardware == hardware)
break;
}
return ap;
}
/* Send an ARP request to resolve IP address target_ip */
static void arp_output(
struct iface *iface,
int16 hardware,
int32 target)
{
struct arp arp;
struct mbuf *bp;
struct arp_type *at;
at = &Arp_type[hardware];
if(iface->output == (int (*)())0)
return;
arp.hardware = hardware;
arp.protocol = at->iptype;
arp.hwalen = at->hwalen;
arp.pralen = sizeof(int32);
arp.opcode = 1;
__builtin_memcpy(arp.shwaddr,iface->hwaddr,at->hwalen);
arp.sprotaddr = iface->addr;
__builtin_memset(arp.thwaddr,0,at->hwalen);
arp.tprotaddr = target;
if((bp = htonarp(&arp)) == (struct mbuf *)0)
return;
(*iface->output)(iface,at->bdcst,
iface->hwaddr,at->arptype,bp);
Arp_stat.outreq++;
}